/*!********************************************************************

  Audacity: A Digital Audio Editor

  @file AudioUnitEffectBase.h

  Dominic Mazzoni
  Leland Lucius

  Paul Licameli split from AudioUnitEffect.h

**********************************************************************/
#ifndef AUDACITY_AUDIOUNIT_EFFECT_BASE_H
#define AUDACITY_AUDIOUNIT_EFFECT_BASE_H

#if USE_AUDIO_UNITS

#include "AudioUnitWrapper.h"
#include "PerTrackEffect.h"

constexpr auto OptionsKey = L"Options";
constexpr auto UseLatencyKey = L"UseLatency";

#define AUDIOUNITEFFECTS_VERSION wxT("1.0.0.0")
/* i18n-hint: the name of an Apple audio software protocol */
#define AUDIOUNITEFFECTS_FAMILY EffectFamilySymbol { wxT("AudioUnit"), XO("Audio Unit") }

class AudioUnitEffectBase : public PerTrackEffect, public AudioUnitWrapper
{
public:
    using Parameters = PackedArray::Ptr<const AudioUnitParameterID>;

    AudioUnitEffectBase(const PluginPath& path, const wxString& name, AudioComponent component, Parameters* pParameters = nullptr,
                        AudioUnitEffectBase* master = nullptr);
    ~AudioUnitEffectBase() override;

    // ComponentInterface implementation

    PluginPath GetPath() const override;
    ComponentInterfaceSymbol GetSymbol() const override;
    VendorSymbol GetVendor() const override;
    wxString GetVersion() const override;
    TranslatableString GetDescription() const override;

    // EffectDefinitionInterface implementation

    EffectType GetType() const override;
    EffectFamilySymbol GetFamily() const override;
    bool IsInteractive() const override;
    bool IsDefault() const override;
    RealtimeSince RealtimeSupport() const override;
    bool SupportsAutomation() const override;

    EffectSettings MakeSettings() const override;
    bool CopySettingsContents(
        const EffectSettings& src, EffectSettings& dst) const override;

    bool SaveSettings(
        const EffectSettings& settings, CommandParameters& parms) const override;
    //! May allocate memory, so should be called only in the main thread
    bool LoadSettings(
        const CommandParameters& parms, EffectSettings& settings) const override;

    OptionalMessage LoadUserPreset(
        const RegistryPath& name, EffectSettings& settings) const override;
    bool SaveUserPreset(
        const RegistryPath& name, const EffectSettings& settings) const override;

    RegistryPaths GetFactoryPresets() const override;
    OptionalMessage LoadFactoryPreset(int id, EffectSettings& settings)
    const override;

    bool InitializePlugin();

    std::shared_ptr<EffectInstance> MakeInstance() const override;

    bool CanExportPresets() const override;

    bool HasOptions() const override;

    // AudioUnitEffect implementation

    static RegistryPath ChoosePresetKey(const EffectSettings& settings);
    static RegistryPath FindPresetKey(const CommandParameters& parms);

    TranslatableString Export(
        const AudioUnitEffectSettings& settings, const wxString& path) const;
    TranslatableString Import(
        AudioUnitEffectSettings& settings, const wxString& path) const;
    /*!
     @param path only for formatting error messages
     @return error message
     */
    TranslatableString SaveBlobToConfig(const RegistryPath& group, const wxString& path, const void* blob, size_t len,
                                        bool allowEmpty = true) const;

    void GetChannelCounts();

    bool MigrateOldConfigFile(
        const RegistryPath& group, EffectSettings& settings) const;
    OptionalMessage
    LoadPreset(const RegistryPath& group, EffectSettings& settings) const;
    bool SavePreset(const RegistryPath& group, const AudioUnitEffectSettings& settings) const;

#if defined(HAVE_AUDIOUNIT_BASIC_SUPPORT)
    bool CreatePlain(wxWindow* parent);
#endif

protected:
    const PluginPath mPath;
    const wxString mName;
    const wxString mVendor;

    bool mInteractive{ false };
};

#endif

#endif
